#######################################################
# Example of FDDEVS network model for a counter 
# which sum up 1 to 10. Every time summing up,
# it generates the value of sum as the output event 
# Author: moonho.hwang@gmail.com
#   Date: Oct.20.2011
#######################################################
from XSY.DEVS.FDDEVS import * 
from XSY.DEVS.CoupledDEVS import *
from XSY.DEVS.SimEngine import SimEngine
from XSY.DEVS.VeriEngine import VeriEngine

class Counter(FDDEVS):
   ''' an atomic FDDEVS of a gun fighter'''
   def __init__(m, n, count_no, parent=None):
      '''constructor'''
      # make the base class FSDEVS
      FDDEVS.__init__(m, n, parent) 
      m.count_no = count_no
      m.sum = 0; m.count = 1
      m.phase='C'      

      # make ports  
      m.addOutputPorts('!c')

   def delta_0(m):
      '''initial state setting'''
      m.phase, m.count, m.sum = 'C', 1, 0 

   def tau(m):
      '''lifespan scheduling function'''
      if m.phase == 'C':
         return 0.5
      else:
         return float('inf')

   def delta_y(m):
      '''output and internal transition function'''
      y = PortValue(m.OP['!c'],m.sum);
      if m.phase == 'C':
         m.sum += m.count
         m.count +=1; 
         if m.count >= m.count_no:
            m.phase = 'D'

   def get_state(m):
      '''get the non-vertex state vector which are mt, loc and dest'''
      return (m.phase, m.count, m.sum)

   def set_state(m, s):
      '''set the non-vertex state vector which are mt, loc and dest'''
      m.phase, m.count, m.sum = s

def runSimulation(md):
   engine = SimEngine(md)

   #---- setting StepByStep and DES simulation only ----
   engine.StepByStep = True
   engine.sfactor = float('inf')
   #----------------------------------------------------
   engine.runInteractiveMenu()

def runVerification(md):
   VE = VeriEngine(md, [], None, None)
   VE.runtimeInteractiveMenu()

if __name__ == '__main__':
   print '''
#######################################################
# Example of FSDEVS network model for a counter 
# which sums up 1 to 10. Every time summing up,
# it generates the summing value as the output event.
# Author: moonho.hwang@gmail.com
#   Date: Oct.20.2011
######################################################
   '''
   md1 = Counter(n="ts1", count_no=5) 

   c = True
   while c:
      s = raw_input('[s]im, [v]eri, e[x]it>')
      if s == 's' or s == 'sim': 
         runSimulation(md1)
      elif s == 'v' or s == 'veri':
         runVerification(md1)
      elif s == 'x' or s == 'exit':
         c = False
      else:
         print('%s is an invalid input!'%s)
      
   print "good bye~!" 
    
